"""
公共方法
"""
from init import *


# 自定义并发数异常
class SemaphoreNumberError(Exception):
    def __init__(self, msg):
        self.__msg = msg

    def __str__(self):
        return self.__msg


def batch_run(func, parma, semaphore, table=None,
              save_func=None, save_path=None):
    """
    异步执行函数  Async execute common function.
    :param func:    # 执行的函数     Execute function.
    :param parma:   # 执行函数的参数   Function's parameter.
    :param semaphore    # 限制的并发数    Limit concurrency.
    :param table:   # 是否美化输出表格  Print prettyTable.
    :return:
    """
    # 程序开始时间    Script's start time.
    start_time = time.perf_counter()
    # 创建任务列表循环  Create loop of task.
    task_loop = asyncio.new_event_loop()
    # 创建任务列表并限制任务并发数    Create task list to limit procedure number.
    task_list = []
    # 循环添加任务    Cyclic add task.
    for task in parma:
        tasks = task_loop.create_task(func(task))
        task_list.append(tasks)
    # 判断任务数量是否大于规定最大值 Check whether the number of task is greater than specified maximum.
    if len(task_list) > 300:
        # 大于规定最大值就报错  If the value is greater than specified maximum, an error is reported.
        raise SemaphoreNumberError('The number of concurrent requests exceeded the upper limit.'
                                   ' The upper limit was 3000 Procedure.')

    else:
        # 没有大于规定值就执行函数  Else execute the function
        task_loop.run_until_complete(asyncio.wait(task_list))
        task_loop.close()
    end_time = time.perf_counter()
    # 美化输出表格    Beautiful output form
    if table:
        print(table)
    if save_path:
        save_func()
    success_color.print(f'Script execute is successful...\nExecute time is:{round(end_time - start_time, 2)}s.')
